package org.sea.mybator.service;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.sea.mybator.model.ColumnEnum;
import org.sea.mybator.model.JdbcType;
import org.sea.mybator.model.TableDesc;
import org.sea.mybator.util.Constants;
import org.sea.mybator.util.Reflection;
import org.sea.mybator.util.Util;

public class Create {

    public static Connection getDataBaseConnection() {
        String connectionUrl = Constants.connectionUrl;
        String jdbcDriver=Constants.jdbcDriver;
        String userName=Constants.userName;
        String password =Constants.password;
        Connection con = null;
        try {
            Class.forName(jdbcDriver);
            con = DriverManager.getConnection(connectionUrl, userName,password);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return con;
    }

    public static List<TableDesc> getTableInfo(String tableName) {
        try {
            Connection con = getDataBaseConnection();
            if (con == null) {
                System.out.println("获得数据库连接失败！");
                return null;
            }
            String dataBaseName = Constants.dataBaseName;
            String schema=Constants.schema;
            List<TableDesc> tableDescList = new ArrayList<TableDesc>();
            DatabaseMetaData dbmd = con.getMetaData();
           
            ResultSet r = dbmd.getColumns(dataBaseName, schema, tableName, null);

            while (r.next()) {
                printTableInfo(r);
                TableDesc tableDesc = new TableDesc();
                tableDesc = getTableDesc(r, tableDesc);
                
                tableDescList.add(tableDesc);
            }

            return tableDescList;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    public static TableDesc getTableDesc(ResultSet r, TableDesc tableDesc) {
        boolean flag = false;
        for (ColumnEnum tempEnum : ColumnEnum.values()) {
            String setMethod = "";
            String propertyName = Util.firstCharToUpperCase(tempEnum.getDesc().toLowerCase(), "_");
            try {
                String value = r.getString(tempEnum.getCode());
                setMethod = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                Reflection.invokePrivateMethod(tableDesc, setMethod, new Object[] { value == null ? "" : value });
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                if (flag)
                    continue;
                System.err.println("调用" + setMethod + "方法失败！");
                flag = true;
            }
        }
        return tableDesc;
    }
    public static void printTableInfo(ResultSet r) {
        String COLUMN_NAME = getPropName(ColumnEnum.COLUMN_NAME, r);
        String TYPE_NAME = getPropName(ColumnEnum.TYPE_NAME, r);
        String COLUMN_SIZE = getPropName(ColumnEnum.COLUMN_SIZE, r);
        String BUFFER_LENGTH = getPropName(ColumnEnum.BUFFER_LENGTH, r);
        String DECIMAL_DIGITS = getPropName(ColumnEnum.DECIMAL_DIGITS, r);
        String NULLABLE = getPropName(ColumnEnum.NULLABLE, r);
        String REMARKS = getPropName(ColumnEnum.REMARKS, r);
        String COLUMN_DEF = getPropName(ColumnEnum.COLUMN_DEF, r);

        System.out.println("COLUMN_NAME 列名称: " + COLUMN_NAME);
        System.out.println("TYPE_NAME 数据类型: " + TYPE_NAME);
        System.out.println("COLUMN_SIZE 列的精度: " + COLUMN_SIZE);
        System.out.println("BUFFER_LENGTH 数据的传输大小: " + BUFFER_LENGTH);
        System.out.println("DECIMAL_DIGITS 列的小数位数: " + DECIMAL_DIGITS);
        System.out.println("NULLABLE 是否可以为 Null: " + NULLABLE);
        System.out.println("REMARKS 注释:" + REMARKS);
        System.out.println("COLUMN_DEF 默认值: " + COLUMN_DEF);
        System.out.println("---------");
    }
    public static String getPropName(ColumnEnum columnEnum, ResultSet r) {
        if (columnEnum == null) {
            System.err.println("getPropName:ColumnEnum==null");
        }
        String result = "";
        for (ColumnEnum tempEnum : ColumnEnum.values()) {
            if (columnEnum != tempEnum)
                continue;
            try {
                result = r.getString(columnEnum.getCode());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return result;
    }
    public static ParseSqlTypeToJavaType getDataTypeConversionProperty() {
        ParseSqlTypeToJavaType javaType = new ParseSqlTypeToJavaType();
        javaType.init();
        javaType.setPropertiyKey("sqlTypeTojavaType");
        javaType.parse();
        javaType.setPropertiyKey("javaBaseType");
        javaType.parse();
        javaType.setPropertiyKey("javaObjectType");
        javaType.parse();
        return javaType;
    }
    
    public String getJdbcType(TableDesc tableDesc) {
        String typeName = tableDesc.getTypeName();
        if ((typeName == null) || ("".equals(typeName))) {
            return "";
        }
        String[] typeNames = typeName.split(" ");
        return typeNames[0].toUpperCase();
    }
    
    public String getNullValue(TableDesc tableDesc) {
        String columnDef = tableDesc.getColumnDef();
        if (columnDef == null) {
            columnDef = "";
        }
        return columnDef;
    }
    public String getQueryConditions(List<JdbcType> jdbcTypeList) {
        if ((jdbcTypeList == null) || (jdbcTypeList.size() == 0)) {
            return "*";
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < jdbcTypeList.size(); i++) {
            sb.append(((JdbcType) jdbcTypeList.get(i)).getColumn()).append(",");
            if ((i > 0) && (i % 9 == 0)) {
                sb.append("\n\t\t");
            }
        }
        String s = sb.toString();
        return s.length() > 0 ? s.substring(0, s.length() - 1) : "*";
    }
}
